/*
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation; either version 2 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *
 *   版权所有  2014-2015 成都星锐蓝海网络科技有限公司
 *   商业许可请联系  +86-18682011860    QQ:66442834
 *   
 */



#include "xyz_hex.h"


/*
 *
 */
int xyz_hex_byte_upper(const xyz_u8_t *b, xyz_sli_t len, xyz_u8_t *buf, xyz_sli_t size)
{
	int i = 0;
	int j = 0;

	for (i = 0; (i < len) && (j < size); ++i) {
		buf[j++] = S_xyz_HEX[(b[i] >> 4) & 0xF];
		buf[j++] = S_xyz_HEX[b[i] & 0xF];
	}
	return j;
}

/*
 *
 */
int xyz_hex_byte_lower(const xyz_u8_t *b, xyz_sli_t len, xyz_u8_t *buf, xyz_sli_t size)
{
	int i = 0;
	int j = 0;

	for (i = 0; (i < len) && (j < size); ++i) {
		buf[j++] = S_xyz_hex[(b[i] >> 4) & 0xF];
		buf[j++] = S_xyz_hex[b[i] & 0xF];
	}
	return j;
}

/*
 *
 */
xyz_u8_t xyz_hex_digit(xyz_u8_t ch)
{
	return ( (ch > '/' && ch < ':') ? (ch - '0') :
			( (ch > '`' && ch < 'g') ? (ch - 'a' + 10) :
			( (ch > '@' && ch < 'G') ? (ch - 'A' + 10) : 0xFF)));
}

/*
 *
 */
xyz_u64_t xyz_hex_str_int(const xyz_u8_t *s, xyz_sli_t len)
{
	xyz_u64_t n = 0;
	int i = 0;

	if (!s || len < 1) {
		return -1;
	}
	if (len > 2) {
		if (('0' == s[0]) && (('x' == s[1]) || ('X' == s[1]))) {
			s += 2;
			len -= 2;
		}
		if (len < 1) {
			return -1;
		}
	}
	if (len > 8) {
		return -1;
	}
	for (i = 0; i < len; i++) {
		n += xyz_hex_digit(s[i]) << ((len - i - 1) * 4);
	}
	return n;
}

/*
 *
 */
int xyz_hex_str_byte(const xyz_u8_t *s, xyz_sli_t len, xyz_u8_t *buf, xyz_sli_t size)
{
	long int i = 0;
	long int j = 0;
	int rlen = 0;

	if (!s || len < 1 || !buf || size < 0) {
		return -1;
	}
	if (len > 2) {
		if (('0' == s[0]) && (('x' == s[1]) || ('X' == s[1]))) {
			s += 2;
			len -= 2;
		}
		if (len < 1) {
			return -1;
		}
	}
	rlen = xyz_hex_str_byte_size(len);
	if (size < rlen) {
		return -1;
	}
	for (i = (len - 1), (j = rlen - 1) ; (i > 0) && (j >=0 ); (i -= 2, j--)) {
		buf[j] = xyz_hex_digit(s[i]);
		buf[j] += (xyz_hex_digit(s[i-1]) << 4);
	}
	if (0 == i) {
		buf[0] = xyz_hex_digit(s[0]);
	}
	return rlen;
}

/*
 *
 */
int xyz_hex_MAC_str_byte(const xyz_u8_t *s, xyz_sli_t len, xyz_u8_t *buf, xyz_sli_t size)
{
	int i = 0;
	int j = 0;

	if (!s || len < 12 || !buf || size < 6) {
		return -1;
	}
	for ( ; (j < 6) && (i < len); ) {
		if (isxdigit(s[i]) && isxdigit(s[i+1])) {
			buf[j] = xyz_hex_digit(s[i]) << 4;
			buf[j] += xyz_hex_digit(s[i+1]);
			i += 2;
			j++;
		} else {
			i += 1;
		}
	}
	return (j == 6 ? 0 : -1);
}

/*
 *
 */
int xyz_hex_MAC_byte_upper(const xyz_u8_t *in, xyz_sli_t len, xyz_u8_t *out, xyz_sli_t size)
{
	int i = 0;
	int j = 0;

	if (!in || len != 6 || !out || size < 17) {
		return -1;
	}
	for ( ; (i < 5) && (j < 15); i++) {
		out[j++] = S_xyz_HEX[(in[i] >> 4) & 0xF];
		out[j++] = S_xyz_HEX[in[i] & 0xF];
		out[j++] = ':';
	}
	out[j++] = S_xyz_HEX[(in[i] >> 4) & 0xF];
	out[j++] = S_xyz_HEX[in[i] & 0xF];
	return j;
}

/*
 *
 */
int xyz_hex_MAC_byte_lower(const xyz_u8_t *in, xyz_sli_t len, xyz_u8_t *out, xyz_sli_t size)
{
	int i = 0;
	int j = 0;

	if (!in || len != 6 || !out || size < 17) {
		return -1;
	}
	for ( ; (i < 5) && (j < 15); i++) {
		out[j++] = S_xyz_hex[(in[i] >> 4) & 0xF];
		out[j++] = S_xyz_hex[in[i] & 0xF];
		out[j++] = ':';
	}
	out[j++] = S_xyz_hex[(in[i] >> 4) & 0xF];
	out[j++] = S_xyz_hex[in[i] & 0xF];
	return j;
}
